﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace ReadTxT
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            ThreadExceptionHandler handler = new ThreadExceptionHandler();
            // 设置没有没捕获的异常在这里强制被捕获
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic);
            // 注册UI线程异常事件
            Application.ThreadException += handler.Form1_UIThreadException;
            // 注册非UI线程异常事件
            AppDomain.CurrentDomain.UnhandledException += handler.CurrentDomain_UnhandledException;
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    internal class ThreadExceptionHandler
    {
        /// <summary>
        /// 捕获UI线程的异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="t"></param>
        public void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
        {
            DialogResult result = DialogResult.Cancel;
            try
            {
                result = ShowThreadExceptionDialog("Windows Forms UI错误", t.Exception);
            }
            catch
            {
                try
                {
                    MessageBox.Show("严重的错误", "Windows Forms UI错误", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
                }
                finally
                {
                    Application.Exit();
                }
            }

            // 点中止时退出程序
            if (result == DialogResult.Abort)
                Application.Exit();
        }

        /// <summary>
        /// 捕获非UI线程的异常,
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            DialogResult result = DialogResult.Cancel;
            try
            {
                Exception ex = (Exception)e.ExceptionObject;
                result = ShowThreadExceptionDialog("非UI线程错误", ex);
            }
            catch (Exception exc)
            {
                try
                {
                    MessageBox.Show("严重的非UI线程错误：" + exc.Message, "非UI线程错误", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
                finally
                {
                    Application.Exit();
                }
            }
            // 点中止时退出程序
            if (result == DialogResult.Abort)
                Application.Exit();
        }

        /// <summary>
        /// 创建错误信息并显示
        /// </summary>
        /// <param name="title"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private DialogResult ShowThreadExceptionDialog(string title, Exception e)
        {
            string errorMsg = "应用程序错误，请联系管理员，" + "错误信息:\n\n";
            errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
            // 在这边记下日志，一般情况下我们可以自定义日志 TODO
            return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
        }
    }
}